package com.etrans.web.gps.business.report.service;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.etrans.web.gps.base.service.BaseService;
import com.etrans.web.gps.business.report.domain.AreaAnalyseCarType;
import com.etrans.web.gps.business.report.domain.AreaAnalyzesVo;
import com.etrans.web.gps.business.report.domain.Vocational;
import com.etrans.web.gps.business.system.service.CommonService;
import com.etrans.web.gps.common.MGTemplete;
import com.etrans.web.gps.util.DateUtil;
import com.mongodb.QueryOperators;

/**
 * 区域分析Service
 * @author         QiLi
 * @ClassName:     AreaAnalyzesService
 *
 */
@Service
public class AreaAnalyzesService extends BaseService{
	
	@Autowired
	public CommonService commonService;
	
	
	/**
	 * 区域分析
	 * @param areaId	区域ID
	 * @param areaIds 
	 * @param analyse_date2 
	 * @param startTime	开始时间
	 * @param endTime	结束时间
	 * @param area_id  	用户权限下区域ID
	 * @return
	 * @throws ParseException 
	 */
	public Map<String,Object> queryAnalyzes(String areaId, Integer[] areaIds, String level, String veidoo,
			String analyse_date, Integer area_id) throws ParseException {
		SimpleDateFormat SDF = new SimpleDateFormat("yyMMdd");
		Set<String> idList = new HashSet<String>();
		HashMap<String,Object> whereMap = new HashMap<String,Object>();
		HashMap<String,Object> mapId = new HashMap<String,Object>();
		HashMap<String, Object> paramId = new HashMap<String, Object>();
		List<HashMap<String,Object>> list=new ArrayList<>();
		List<HashMap<String,Object>> listAreaIds=new ArrayList<>();
		HashMap<String, Object> params = new HashMap<>();
		if(areaIds!=null && areaIds.length>0){
			List<Integer> Ids = new ArrayList<>();
			 if(level!=null&&!"".equals(level)&&!level.equals("1")){
				 String ids ="";
				for (Integer id : areaIds) {
					ids += id + ",";
				}
				params.put("level", level);
				params.put("areaIds", ids.substring(0, ids.length()-1));
				listAreaIds = commonService.findAreaIdByLevelAndIds(params);
				for (HashMap<String, Object> hashMap : listAreaIds) {
					String id=(Long)hashMap.get("ID")+"";
					Ids.add(Integer.parseInt(id));
					}
				}else{
					Ids.add(areaIds[0]);
				}
			HashMap<String,Object> whereMap_Area = new HashMap<String,Object>();
			whereMap_Area.put(QueryOperators.IN,Ids);
			whereMap.put("area_id", whereMap_Area);
		}
		if(areaId!=null && !"".equals(areaId)){
			mapId.put("ID", areaId);
			list.add(mapId);
		}else{
			paramId.put("FullID", String.format("%08d",area_id));
			list = commonService.queryAreaTree(paramId);
		
		}
		String id=null;
		List<Document> reslist = null;
		HashMap<String,Object> whereMapparam = new HashMap<String,Object>();
		if(analyse_date!=null&&!"".equals(analyse_date)){
			if("day".equals(veidoo)){
			if(list != null && list.size() > 0){
				for (HashMap<String, Object> hashMap : list) {
					id = SDF.format(DateUtil.getStrToDate(analyse_date))+":"+hashMap.get("ID");
					idList.add(id);
				}
			}
				whereMapparam.put(QueryOperators.IN,idList);
				whereMap.put("_id", whereMapparam);
				reslist = MGTemplete.findDocuments("egov", "area_swap",whereMap);
			}else if ("week".equals(veidoo)) {
				int year = Integer.parseInt((analyse_date).split("-")[0]);
				int week = Integer.parseInt((analyse_date).split("-")[1]);
				Map<String,Object> map =DateUtil.getYearAndWeekByDate(year, week);
					if(list!=null && list.size()>0){
						for (HashMap<String, Object> hashMap : list) {
							id = SDF.format(DateUtil.getStrToDate((String)map.get("Monday")))+":"+hashMap.get("ID");
							idList.add(id);
						}
					}
				whereMapparam.put(QueryOperators.IN,idList);
				whereMap.put("_id", whereMapparam);
				reslist = MGTemplete.findDocuments("egov", "area_swap_week",whereMap);
			}else if ("month".equals(veidoo)) {
					if(list!=null && list.size()>0){
						for (HashMap<String, Object> hashMap : list) {
							id = SDF.format(DateUtil.getStrToDate(analyse_date+"-01"))+":"+hashMap.get("ID");
							idList.add(id);
						}
					}
				whereMapparam.put(QueryOperators.IN,idList);
				whereMap.put("_id", whereMapparam);
				reslist = MGTemplete.findDocuments("egov", "area_swap_curMonth",whereMap);
			}
		}	
		Map<String,Object> resultMap = new HashMap<String,Object>();
		List<AreaAnalyzesVo> listAnalyzes=null;
		List<AreaAnalyseCarType> clist = null;
		AreaAnalyseCarType  catType = null;
		if(reslist!=null){
			Document trade_obj =null;
			AreaAnalyzesVo  Analyzes;
			String json;
			clist = new ArrayList<AreaAnalyseCarType>();
			catType = new AreaAnalyseCarType();
			catType.setDangerCar("车辆总数|入网数(率)|上线数(率)");
			catType.setRegularBus("车辆总数|入网数(率)|上线数(率)");
			catType.setTouringCar("车辆总数|入网数(率)|上线数(率)");
			clist.add(catType);
			listAnalyzes = new ArrayList<AreaAnalyzesVo>();
			for (Document document : reslist) {
				trade_obj = (Document)document.get("trade_obj");
				AreaAnalyseCarType carType = getVocational(trade_obj,(String)document.get("area_name"));
				clist.add(carType);
				json = JSONObject.toJSONString(document);
				Analyzes = JSONObject.toJavaObject(JSONObject.parseObject(json),AreaAnalyzesVo.class);
				listAnalyzes.add(Analyzes);
			}
			Collections.sort(listAnalyzes,Collections.reverseOrder(new Comparetores()));
			//排名
			sortList(listAnalyzes);
		}
		resultMap.put("listAnalyzes", listAnalyzes);
		resultMap.put("list",clist);
		return resultMap;
	}
	private AreaAnalyseCarType getVocational(Document d,String areaName){
		DecimalFormat DFS = new DecimalFormat("0.00");
		Document document;
		String json;
		Vocational vo;
		AreaAnalyseCarType carType = new AreaAnalyseCarType(); 
		String str = null;
		carType.setAreaName(areaName);
		
		document =(Document)d.get("1");
		json = JSONObject.toJSONString(document);
		vo = JSONObject.toJavaObject(JSONObject.parseObject(json),Vocational.class);
		str =  vo.getVehicle_count()+"|"+vo.getVehicle_access_count()+"("+(vo.getVehicle_access_rate()>1?DFS.format(vo.getVehicle_access_rate()):vo.getVehicle_access_rate()==0.0?0:vo.getVehicle_access_rate())+"%)|"+vo.getVehicle_online_count()+"("+(vo.getVehicle_online_rate()>1?DFS.format(vo.getVehicle_online_rate()):vo.getVehicle_online_rate()==0.0?0:vo.getVehicle_online_rate())+"%)";
		carType.setRegularBus(str);
		
		document =(Document)d.get("2");
		json = JSONObject.toJSONString(document);
		vo = JSONObject.toJavaObject(JSONObject.parseObject(json),Vocational.class);
		str =  vo.getVehicle_count()+"|"+vo.getVehicle_access_count()+"("+(vo.getVehicle_access_rate()>1?DFS.format(vo.getVehicle_access_rate()):vo.getVehicle_access_rate()==0.0?0:vo.getVehicle_access_rate())+"%)|"+vo.getVehicle_online_count()+"("+(vo.getVehicle_online_rate()>1?DFS.format(vo.getVehicle_online_rate()):vo.getVehicle_online_rate()==0.0?0:vo.getVehicle_online_rate())+"%)";
		carType.setTouringCar(str);
		
		document =(Document)d.get("3");
		json = JSONObject.toJSONString(document);
		vo = JSONObject.toJavaObject(JSONObject.parseObject(json),Vocational.class);
		str =  vo.getVehicle_count()+"|"+vo.getVehicle_access_count()+"("+(vo.getVehicle_access_rate()>1?DFS.format(vo.getVehicle_access_rate()):vo.getVehicle_access_rate()==0.0?0:vo.getVehicle_access_rate())+"%)|"+vo.getVehicle_online_count()+"("+(vo.getVehicle_online_rate()>1?DFS.format(vo.getVehicle_online_rate()):vo.getVehicle_online_rate()==0.0?0:vo.getVehicle_online_rate())+"%)";
		carType.setDangerCar(str);
		
		return carType;
	}
	
	/**
	 * 柱形图
	 * @param area_id
	 * @param veidoo
	 * @param analyse_date
	 * @return
	 */
	public List<AreaAnalyzesVo> getShadowRegion(String area_id, String veidoo, String analyse_date) {
		SimpleDateFormat SDF = new SimpleDateFormat("yyMMdd");
		Set<String> idList = new HashSet<String>();
		HashMap<String,Object> whereMap = new HashMap<String,Object>();
		String id=null;
		List<Document> reslist = null;
		HashMap<String,Object> whereMapparam = new HashMap<String,Object>();
		if(analyse_date!=null&&!"".equals(analyse_date)){
			if("day".equals(veidoo)){
				if(area_id!=null&&!"".equals(area_id)){
					try {
						id = SDF.format(DateUtil.getStrToDate(analyse_date))+":"+area_id;
					} catch (ParseException e) {
						e.printStackTrace();
					}
				}
				whereMap.put("_id", id);
				reslist = MGTemplete.findDocuments("egov", "area_swap",whereMap);
			}else if ("week".equals(veidoo)) {
				int year = Integer.parseInt((analyse_date).split("-")[0]);
				int week = Integer.parseInt((analyse_date).split("-")[1]);
				Map<String,Object> map =DateUtil.getYearAndWeekByDate(year, week);
				if(area_id!=null&&!"".equals(area_id)){
					List<String> time = DateUtil.getDates((String)map.get("Monday"),(String)map.get("Sunday"));
					for (String string : time) {
						try {
							id = SDF.format(DateUtil.getStrToDate(string))+":"+area_id;
						} catch (ParseException e) {
							e.printStackTrace();
						}
						idList.add(id);
					}
				}		
				whereMapparam.put(QueryOperators.IN,idList);
				whereMap.put("_id", whereMapparam);
				reslist = MGTemplete.findDocuments("egov", "area_swap",whereMap);
			}else if ("month".equals(veidoo)) {
				if(area_id!=null&&!"".equals(area_id)){
					List<String> time = DateUtil.getMonday(analyse_date);
					for (String string : time) {
						try {
							id =SDF.format(DateUtil.getStrToDate(string))+":"+area_id;
						} catch (ParseException e) {
							e.printStackTrace();
						}
						idList.add(id);
					}
				}
				whereMapparam.put(QueryOperators.IN,idList);
				whereMap.put("_id", whereMapparam);
				reslist = MGTemplete.findDocuments("egov", "area_swap_week",whereMap);
			}
		}
		List<AreaAnalyzesVo> listAnalyzes = new ArrayList<AreaAnalyzesVo>();
		AreaAnalyzesVo  Analyzes;
		if(reslist != null && reslist.size() > 0){
			for (Document document : reslist) {
				String json = JSONObject.toJSONString(document);
				Analyzes = JSONObject.toJavaObject(JSONObject.parseObject(json),AreaAnalyzesVo.class);
				listAnalyzes.add(Analyzes);
			}
		}
		return listAnalyzes;
	}
	
	/**
	 * 
	 * @Description:TODO
	 * @author RenweiWu
	 * @date 2017年9月5日
	 * @ClassName:  Comparetores  
	 * @param: Comparator<T>
	 */
	public static class Comparetores implements Comparator<AreaAnalyzesVo>{
		public int compare(AreaAnalyzesVo analyzes1, AreaAnalyzesVo analyzes2) {
	        int maxs=analyzes1.getScore()-analyzes2.getScore();
	         if(maxs==0){
	        	 int a1=(analyzes1.getTrack_normal()+analyzes1.getException_track_count())<=0?1:(analyzes1.getTrack_normal()+analyzes1.getException_track_count());
	        	 int a2=(analyzes2.getTrack_normal()+analyzes2.getException_track_count())<=0?1:(analyzes2.getTrack_normal()+analyzes2.getException_track_count());
	        	 int maxn = (int)(((double)analyzes1.getException_track_count()/a1)-((double)analyzes2.getException_track_count()/a2));
	        	 if (maxn==0) {
					return analyzes1.getScore()<=analyzes2.getScore()?-1:1;
				} else {
					return maxn;
				}
	         }else{
	 	        return maxs;
	         }
		}		
	}

	/**
	 * 获取区域名
	 * @param map
	 * @return
	 */
	public String queryAreaName(HashMap<String, Object> map) {
		return this.selectOne("areaAnalyzesQuery.queryAreaName", map);
	}
	
	/**
	 * 根据分数排名
	 * @param subList
	 */
	private void sortList(List<AreaAnalyzesVo> subList) {
		int conut=1;
		for (int i = 0; i < subList.size(); i++) {
			int platScore1 = subList.get(i).getScore();
			if (i < subList.size()-1) {
				int platScore2 = subList.get(i+1).getScore();
				if (platScore1 != platScore2) {
					subList.get(i).setRanking(conut);
					conut++;
				}else {
					subList.get(i).setRanking(conut);
				}
			}else {
				subList.get(i).setRanking(conut);
			}
		}
	}

}